Skip to content

Adopt webcore auth via wrapper Manager - #156

Open
sarg3nt wants to merge 1 commit into
feature/webcore-adoptionfrom
feature/webcore-auth
Open

Adopt webcore auth via wrapper Manager#156
sarg3nt wants to merge 1 commit into
feature/webcore-adoptionfrom
feature/webcore-auth

Conversation

@sarg3nt

@sarg3nt sarg3nt commented Jul 4, 2026

Copy link
Copy Markdown
Owner

Summary

Closes #148. Stacked on #155 (retargets to main automatically when that merges).

The security-critical auth mechanics (DB-validated session tokens, constant-time login, CSRF, password change/reset, the -tags dev loopback bypass) now come from webcore/core/auth. Gearbox's auth.Manager is a thin wrapper with an unchanged public API — all 60+ GetUserFromContext call sites, handlers, templates, and main.go compile untouched. Net −1131 lines.

  • adapter.go: authUser adapts *models.User to webcore's AuthUser (adapter struct because the ID field collides with the interface's ID() method), preserving gearbox's historical status messages; userStore/auditLogger map webcore's interfaces onto database.DB (audit action strings are identical — no mapping).
  • Same cookie name, session keys, and secret — existing sessions survive the cutover.
  • RBAC/permissions, gear/box context helpers, RequireAdmin, and SetPasswordAndEmail stay gearbox-side.
  • WebAuthn deliberately untouched: gearbox encodes credential IDs as []byte(user.ID); webcore's adapter uses uint64 BE — switching would invalidate every registered passkey.
  • Session-lifetime tests (absolute timeout, legacy anchoring, cookie MaxAge shrink) moved to webcore with the internals they poke (webcore cf94647).

Verification

go build + go test green on both default and -tags dev. Full E2E smoke suite against a live server + real SQLite store:

# Flow Result
1 Wrong password no session cookie issued
2 Unknown user identical handling (no enumeration)
3 Correct login 303 → /, gearbox-session set
4 Authed page 200
5 CSRF reject (wired route) redirect ?error=Invalid+CSRF+token
6 Logout server-side token cleared; old cookie → /login
7 Password change old session invalidated; new password logs in
8 Dev loopback bypass (webcore impl) fires; banner logged
9 Lockout 5 failures → locked_until set → correct password rejected, no session

Passkey ceremony not smoke-tested (needs an authenticator); the WebAuthn code path is byte-identical to main and CreateSessionForUser delegation is covered by webcore's unit suite.

🤖 Generated with Claude Code

The security-critical auth mechanics now live in webcore/core/auth; gearbox's
Manager is a thin wrapper with an unchanged public API, so all 60+ handler
call sites, main.go wiring, and templates compile untouched.

- adapter.go: authUser adapts *models.User to webcore's AuthUser (adapter
  struct because User.ID the field collides with ID() the method), preserving
  gearbox's historical status messages; userStore maps webcore's UserStore
  onto database.DB; auditLogger writes webcore's audit actions (string values
  identical to gearbox's AuditAction*) to the audit_logs table.
- auth.go: 827 lines -> 216. Login/Logout/GetUser/CSRF/ExtendSession/
  ChangePassword/SetPassword/reset flows delegate to webcore; gearbox keeps
  SetPasswordAndEmail (atomic combined update), permissions/RBAC, GetDB,
  LogAudit. Same cookie name, session keys, and secret — existing sessions
  survive the cutover.
- middleware.go: RequireAuth delegates to webcore (which owns the login
  redirect + dev bypass) and re-maps the user into gearbox's context as a
  concrete *models.User; RequirePasswordChange/RequireCSRF delegate.
  RequireAdmin + all gear/box context helpers stay.
- password.go/security.go: re-exports of webcore's policy + token helpers
  (identical constants).
- dev_bypass_on/off.go: bypass logic moved to webcore (-tags dev only);
  gearbox keeps seeding (unusable random-password hash) and the banner.
- WebAuthn deliberately untouched: gearbox encodes credential IDs as
  []byte(user.ID); webcore's adapter uses uint64 BE — switching would
  invalidate every registered passkey.
- Tests: the absolute-timeout, legacy-anchoring, and cookie-MaxAge tests
  moved to webcore/core/auth with the internals they poke; SetSecure is now
  asserted behaviorally via the Set-Cookie attribute.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant